const modules = {};

// eslint-disable-next-line no-unused-vars
function define(name, deps, factory) {
  let pending = deps.length;
  let resolvedDeps = new Array(pending);

  deps.forEach(function(dep, index) {
    if (modules[dep]) {
      resolvedDeps[index] = modules[dep];
      --pending;
    } else {
      // eslint-disable-next-line no-undef
      loadScript(dep + '.js', function() {
        console.log('define: onload ' + dep + '.js');
        resolvedDeps[index] = modules[dep];
        --pending;
        if (pending === 0) {
          modules[name] = factory.apply(null, resolvedDeps);
        }
      });
    }
  });
  
  if (pending === 0) {
    modules[name] = factory.apply(null, resolvedDeps);
  }
}

// eslint-disable-next-line no-unused-vars
function require(deps, callback) {
  let pending = deps.length;
  const resolvedDeps = new Array(pending);

  deps.forEach(function(dep, index) {
    if (modules[dep]) {
      resolvedDeps[index] = modules[dep];
      --pending;
    } else {
      loadScript(dep + '.js', function() {
        console.log('require: onload ' + dep + '.js');
        resolvedDeps[index] = modules[dep];
        --pending;
        if (pending === 0) {
          callback.apply(null, resolvedDeps);
        }
      });
    }
  });

  if (pending === 0) {
    callback.apply(null, resolvedDeps);
  }

  function loadScript(url, callback) {
    const script = document.createElement('script');
    script.src = url;
    script.onload = callback || function() {};
    document.head.appendChild(script);
  }
}